< previous page page_245 next page >

Page 245
string. When the API function returns, the contents of that ANSI string are copied into Visual Basic's Unicode string.
The numbered arrows in Figure S27-1 represent the different pointers that one can pass to API functions:
Pointer 1 is the address of the Visual Basic String variable that contains the pointer to the Visual Basic string data (BSTR string). You can obtain this address in the same way you obtain the address of any Visual Basic variable: by using the VarPtr operator.
Pointer 2 is the value of the pointer for the stringthe address of the start of the Visual Basic string data (BSTR string). You can obtain this address in Visual Basic using the StrPtr operator.
Pointer 3 is the address of the temporary variable that contains the pointer to the temporary ANSI string created by Visual Basic (BSTR string). This is the address you pass when you pass a string variable to an API function by reference.
Pointer 4 is the value of the pointer for the temporary ANSI string (BSTR string). This is the address you pass when you pass a string variable to an API function by value.
The vast majority of API functions using string pointers are declared as LPSTR, or ANSI, strings. The only pointer in the figure that points to an ANSI string is pointer 4, which explains why most string variables are passed by value.
The StringFromCLSID function requires a Unicode string, so clearly pointers 3 and 4 are out of the question. If the ppsz parameter was declared just as LPOLESTR, pointer 2 would work, since an LPOLESTR is a pointer to the actual Unicode string data. That's why you can use the StrPtr operator to obtain valid parameters for many API functions that use OLE strings. Just declare the parameter ByVal As Long and pass the value obtained using the StrPtr operator on the string. You must, of course, make sure that the string is preallocated to a length sufficient to hold any data loaded into the string by the API function.
That leaves pointer 1 as the only possible remaining solution for the StringFromCLSID function. And at first glance, it looks like it might work. Pointer 1 is a pointer to a BSTR, which contains a pointer to the string. And an LPOLESTR * parameter is a pointer to a pointer. So this should work, right?
Wrong. Why? Because an LPOLESTR is not a pointer to a BSTR. It's a pointer to a regular NULL-terminated string. A BSTR is allocated by the OLE string management system, and the string data is preceded by the length of the string. An LPOLESTR is just a generic pointer to a string. Figure S27-2 shows the ppsz parameter from the perspective of the StringFromCLSID function. The function

 
< previous page page_245 next page >